using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;
using System.Windows.Forms;
using PluginFrame;

namespace PcrDataAnalysis
{
    public class QualitativeAnalysis : IAnalysisExecutor
    {
        protected ResourceManager mResourceManager;

        protected IApplication mApplication;

        protected IConfigurationService mConfigurationService;

        protected IAnalysisAlgorithmConfiguration mAnalysisConfiguration;

        protected IMiscService mMiscService;

        public QualitativeAnalysis(IApplication application)
        {
            mApplication = application;
            mConfigurationService = (IConfigurationService)mApplication.GetService("ConfigurationService");
            mAnalysisConfiguration = mConfigurationService.AnalysisConfiguration;
            mMiscService = (IMiscService)mApplication.GetService("MiscService");
            mResourceManager = ResourceManager.CreateFileBasedResourceManager("PcrDataAnalysis", mApplication.GetResourceFolder() + GetType().Namespace + "\\", null);
        }

        public virtual AnalysisError Execute(Dictionary<string, List<IPcrCell>> projectCells, IPcrExperiment pcrExperiment, IAbsoluteAnalysisParameterConfiguration analysisOption, IMeltingAnalysisParameterConfiguration meltingOption)
        {
            AnalysisParameterConfiguration analysisParameterConfiguration = analysisOption as AnalysisParameterConfiguration;
            if (!analysisParameterConfiguration.IsNeedReAnalysis)
            {
                return AnalysisError.NA;
            }
            int projectChannel = analysisParameterConfiguration.ProjectChannel;
            int num = 1;
            IBaseLineNormalization baseLineNormalization = new NormalizationCreator().Creator(mApplication, analysisOption.BaselineOptimization);
            IQuantitativeAnalysisResult quantitativeAnalysisResult = new QuantitativeAnalysisResult();
            quantitativeAnalysisResult.ProjectChannel = projectChannel;
            quantitativeAnalysisResult.ProjectName = analysisParameterConfiguration.ProjectName;
            quantitativeAnalysisResult.PcrExperimentStatus = PcrExperimentStatus.AccomplishedSaved;
            pcrExperiment.SetAnalysisResult(analysisOption.Project, projectChannel, analysisParameterConfiguration.TargetIndex, quantitativeAnalysisResult);
            List<IPcrCell> sameTypeCells = GetSameTypeCells(projectCells, string.Empty, false);
            CalculateCellsCycleValue(sameTypeCells, pcrExperiment, analysisOption, analysisOption.ManualThreshold, baseLineNormalization, meltingOption);
            if (analysisParameterConfiguration.ProjectProperty == null)
            {
                analysisParameterConfiguration.ProjectProperty = mConfigurationService.CreateAbsoluteProjectProperty(analysisParameterConfiguration.ProjectName, string.Empty, mConfigurationService.QuantitativeThreshold, mConfigurationService.QualitativeThreshold, mConfigurationService.QualitativeResultUnit, mConfigurationService.QuantitativeResultUnit, false, false, 0.0, 0.0);
            }
            double qualitativeThreshold = (analysisParameterConfiguration.ProjectProperty as IAbsoluteProjectProperty).QualitativeThreshold;
            bool isSetQualitativeGreyZone = (analysisParameterConfiguration.ProjectProperty as IAbsoluteProjectProperty).IsSetQualitativeGreyZone;
            double qualitativeGreyZone = (analysisParameterConfiguration.ProjectProperty as IAbsoluteProjectProperty).QualitativeGreyZone;
            foreach (IPcrCell item in sameTypeCells)
            {
                bool flag = item.CellPosition == "H4";
                double cycleValue = item.GetCycleValue(projectChannel);
                if (string.IsNullOrEmpty(item.Project.QualitativeNegativeConlusion))
                {
                    item.Project.QualitativeNegativeConlusion = mResourceManager.GetString("NegativeString");
                }
                if (string.IsNullOrEmpty(item.Project.QualitativePositiveConlusion))
                {
                    item.Project.QualitativePositiveConlusion = mResourceManager.GetString("PositiveString");
                }
                if (double.IsNaN(cycleValue))
                {
                    item.SetCellInformation("InterpretationKey", projectChannel, item.Project.QualitativeNegativeConlusion);
                    item.SetCellInformation("InterpretationColorKey", projectChannel, item.Project.QualitativeNegativeColor.ToArgb().ToString());
                }
                else if (cycleValue > qualitativeThreshold)
                {
                    item.SetCellInformation("InterpretationKey", projectChannel, item.Project.QualitativeNegativeConlusion);
                    item.SetCellInformation("InterpretationColorKey", projectChannel, item.Project.QualitativeNegativeColor.ToArgb().ToString());
                }
                else if (isSetQualitativeGreyZone)
                {
                    if (cycleValue > qualitativeGreyZone)
                    {
                        if (string.IsNullOrEmpty(item.Project.QualitativeGreyConlusion))
                        {
                            item.Project.QualitativeGreyConlusion = mResourceManager.GetString("ReTestString");
                        }
                        item.SetCellInformation("InterpretationKey", projectChannel, item.Project.QualitativeGreyConlusion);
                        item.SetCellInformation("InterpretationColorKey", projectChannel, item.Project.QualitativeGreyColor.ToArgb().ToString());
                    }
                    else
                    {
                        item.SetCellInformation("InterpretationKey", projectChannel, item.Project.QualitativePositiveConlusion);
                        item.SetCellInformation("InterpretationColorKey", projectChannel, item.Project.QualitativePositiveColor.ToArgb().ToString());
                    }
                }
                else
                {
                    item.SetCellInformation("InterpretationKey", projectChannel, item.Project.QualitativePositiveConlusion);
                    item.SetCellInformation("InterpretationColorKey", projectChannel, item.Project.QualitativePositiveColor.ToArgb().ToString());
                }
                item.SetIsNeedReAnalysis(projectChannel, false);
                Application.DoEvents();
            }
            analysisParameterConfiguration.IsNeedReAnalysis = false;
            quantitativeAnalysisResult.PcrExperimentStatus = PcrExperimentStatus.AnalysisAccomplished;
            return AnalysisError.NA;
        }

        protected virtual List<IPcrCell> GetSameTypeCells(Dictionary<string, List<IPcrCell>> projectCells, string typeString, bool isSame)
        {
            string[] detectionTypeArray = mConfigurationService.GetDetectionTypeArray(PcrSystemType.AbsoluteAnalysis);
            string strB = detectionTypeArray[6];
            List<IPcrCell> list = new List<IPcrCell>();
            IEnumerator enumerator = projectCells.Keys.GetEnumerator();
            while (enumerator.MoveNext())
            {
                string text = enumerator.Current.ToString();
                if (isSame)
                {
                    if (text.CompareTo(typeString) == 0 && projectCells[text] != null && projectCells[text].Count > 0)
                    {
                        list.AddRange(projectCells[text]);
                        break;
                    }
                }
                else if (text.CompareTo(typeString) != 0 && text.CompareTo(strB) != 0 && projectCells[text] != null && projectCells[text].Count > 0)
                {
                    list.AddRange(projectCells[text]);
                }
            }
            return list;
        }

        protected virtual void CalculateCellsCycleValue(List<IPcrCell> pcrCells, IPcrExperiment pcrExperiment, IAbsoluteAnalysisParameterConfiguration analysisOption, double thresholdResult, IBaseLineNormalization baseLineNormalization, IMeltingAnalysisParameterConfiguration meltingOption)
        {
            int projectChannel = (analysisOption as AnalysisParameterConfiguration).ProjectChannel;
            for (int i = 0; i < pcrCells.Count; i++)
            {
                baseLineNormalization.Execute(pcrCells[i], analysisOption, projectChannel, true);
                pcrCells[i].InitializeAmplificationCurveSeries(projectChannel);
                pcrCells[i].InitializeRawCurveSeries(projectChannel);
                if (pcrExperiment.SystemType == PcrSystemType.GeneScan)
                {
                    pcrCells[i].InitializeHRMCurveSeries(projectChannel);
                }
                else
                {
                    pcrCells[i].InitializeMeltingCurveSeries(projectChannel);
                }
                pcrCells[i].IsSetInterpResult = false;
                double num = CalculateLightDataInterp(pcrCells[i], projectChannel, thresholdResult);
                if (pcrExperiment.SystemType == PcrSystemType.AbsoluteAnalysis)
                {
                    try
                    {
                        pcrCells[i].CalculateMeltingDevCurve(projectChannel, meltingOption);
                    }
                    catch (Exception)
                    {
                    }
                }
                pcrCells[i].AddPointToRawCurve(projectChannel, false, 0);
                if (mConfigurationService.IsSetCtThreshold && num <= (double)mConfigurationService.CtThreshold)
                {
                    num = double.NaN;
                }
                pcrCells[i].SetCycleValue(projectChannel, num);
                string value = (double.IsNaN(num) ? "No Ct" : num.ToString(mAnalysisConfiguration.CTValueFormatString));
                pcrCells[i].SetCellInformation("CycleValueKey", projectChannel, value);
            }
        }

        public double CalculateLightDataInterp(IPcrCell pcrCell, int channelIndex, double threshold)
        {
            try
            {
                IPcrExperiment pcrExperiment = pcrCell.PcrExperiment;
                IPcrExperimentProject pcrExperimentProject = pcrExperiment.Projects[0];
                List<double> list = new List<double>();
                List<int> list2 = new List<int>();
                List<double>[] array = null;
                double num = 0.0;
                double num2 = 0.0;
                int amplificationStopCycle = pcrExperiment.AmplificationStopCycle;
                if (pcrCell.IsSetInterpResult)
                {
                    array = pcrCell.InterpResult;
                }
                else
                {
                    double[] amplificationLightDataArray = pcrCell.GetAmplificationLightDataArray(channelIndex);
                    List<double> list3 = new List<double>(amplificationLightDataArray.Length);
                    List<double> list4 = new List<double>(amplificationLightDataArray.Length);
                    int num3 = amplificationLightDataArray.Length;
                    if (pcrExperimentProject.PcrProgram.PcrExperimentType != 0)
                    {
                        num3 = pcrExperimentProject.PcrProgram.AmplificationDetectionCount;
                        if (pcrExperiment.SystemType == PcrSystemType.GeneScan)
                        {
                            num = pcrExperiment.PcrProgram.HRMSegments[0].StartDegree;
                            num2 = pcrExperiment.PcrProgram.HRMSegments[0].StepInterval;
                        }
                        else
                        {
                            num = pcrExperiment.PcrProgram.MeltingSegments[0].StartDegree;
                            num2 = pcrExperiment.PcrProgram.MeltingSegments[0].StepInterval;
                        }
                        pcrExperiment.MeltingStartCycle = num3 + 1;
                        pcrExperiment.MeltingStopCycle = amplificationLightDataArray.Length;
                        if (pcrExperiment.IsContinueHRM)
                        {
                            double stopDegree = pcrExperiment.PcrProgram.HRMSegments[0].StopDegree;
                            num2 = (stopDegree - num) / (double)(pcrExperiment.MeltingStopCycle - pcrExperiment.MeltingStartCycle);
                        }
                        List<double> list5 = new List<double>();
                        for (int i = pcrExperiment.MeltingStartCycle; i <= pcrExperiment.MeltingStopCycle; i++)
                        {
                            double num4 = num + (double)(i - pcrExperiment.MeltingStartCycle) * num2;
                            num4 += pcrExperiment.HRMRamp * 0.057 * (double)(mConfigurationService.CellIDToScanID[pcrCell.CellID - 1] - 96);
                            list5.Add(num4);
                            pcrCell.SetMeltingCurveLightData(channelIndex, num4, amplificationLightDataArray[i - 1]);
                        }
                    }
                    for (int j = 1; j <= num3; j++)
                    {
                        if (!double.IsNaN(amplificationLightDataArray[j - 1]))
                        {
                            list3.Add(amplificationLightDataArray[j - 1]);
                            list4.Add(j);
                        }
                    }
                    if (list4.Count != 0 && list3.Count != 0)
                    {
                        try
                        {
                            array = mMiscService.InterpData(list4.ToArray(), list3.ToArray(), mAnalysisConfiguration.CurveInterpInterval, true);
                        }
                        catch (Exception)
                        {
                            array = null;
                        }
                    }
                    pcrCell.InterpResult = array;
                }
                if (array == null)
                {
                    return double.NaN;
                }
                int count = array[0].Count;
                if (count <= 1)
                {
                    return double.NaN;
                }
                bool flag = array[1][0] <= threshold;
                for (int k = 0; k < count; k++)
                {
                    double num5 = array[1][k];
                    double num6 = array[0][k];
                    if (!pcrCell.IsSetInterpResult && num6 <= (double)amplificationStopCycle)
                    {
                        pcrCell.SetCurveLightData(channelIndex, num6, num5);
                    }
                    if (num5 >= threshold && num6 <= (double)amplificationStopCycle && flag)
                    {
                        list.Add(num6);
                        list2.Add(k);
                    }
                    flag = num5 <= threshold;
                }
                pcrCell.IsSetInterpResult = true;
                if (list.Count > 0)
                {
                    int num7 = list2[list2.Count - 1];
                    double num8 = array[1][num7];
                    if (num8 >= threshold)
                    {
                        double num9 = array[1][num7 - 1];
                        if (num8.Equals(num9))
                        {
                            return num7;
                        }
                        double num10 = (num8 - num9) / (array[0][num7] - array[0][num7 - 1]);
                        double num11 = num8 - num10 * list[list2.Count - 1];
                        return (threshold - num11) / num10;
                    }
                }
                return double.NaN;
            }
            catch (Exception)
            {
                return double.NaN;
            }
        }
    }
}
